/*
 * 
 *  This file is part of Sourceprojects.org Lycia Copyright 2010 noctarius
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 * 
 */
package org.sourceprojects.xmlparser.internal.resolver;

import java.io.InputStream;

import org.sourceprojects.xmlparser.NamespaceResolver;
import org.sourceprojects.xmlparser.internal.dom.LSInputImpl;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSInput;

/**
 * 
 * @author noctarius
 * @since 0.0.1
 */
public class BasicNamespaceResolver implements NamespaceResolver {
	private final NamespaceResolverHandlerContainer[] containers;
	private final ClassLoader classLoader;

	public BasicNamespaceResolver(
			final NamespaceResolverHandlerContainer[] containers,
			final ClassLoader classLoader) {
		this.containers = containers;
		this.classLoader = classLoader;
	}

	@Override
	public LSInput getInput(final String type, final String namespaceURI,
			final String publicId, final String systemId, final String baseURI) {

		for (final NamespaceResolverHandlerContainer container : containers) {
			if (container.getNamespaceURI().equals(namespaceURI)
					|| container.getNamespaceURI().equals(systemId)) {
				final InputStream is = getByteStream(container
						.getRedirectedURI());

				final LSInput input = new LSInputImpl();
				input.setBaseURI(baseURI);
				input.setPublicId(publicId);
				input.setSystemId(systemId);
				input.setByteStream(is);

				return input;
			}
		}

		try {
			final DOMImplementationRegistry registry = DOMImplementationRegistry
					.newInstance();
			final DOMImplementationLS impl = (DOMImplementationLS) registry
					.getDOMImplementation("XML").getFeature("LS", "");

			return impl.createLSInput();
		} catch (final ClassCastException e) {
			return new LSInputImpl();
		} catch (final ClassNotFoundException e) {
			return new LSInputImpl();
		} catch (final InstantiationException e) {
			return new LSInputImpl();
		} catch (final IllegalAccessException e) {
			return new LSInputImpl();
		}
	}

	@Override
	public String getNamespaceURI() {
		return null;
	}

	private InputStream getByteStream(final String uri) {
		return classLoader.getResourceAsStream(uri);
	}

	public static class NamespaceResolverHandlerContainer {
		private final String namespaceURI;
		private final String redirectedURI;

		public NamespaceResolverHandlerContainer(final String namespaceURI,
				final String redirectedURI) {
			this.namespaceURI = namespaceURI;
			this.redirectedURI = redirectedURI;
		}

		public String getNamespaceURI() {
			return namespaceURI;
		}

		public String getRedirectedURI() {
			return redirectedURI;
		}
	}
}
